[phasorloop~] phasor with loop points
Outps a phasor ramp signal with adjustable loop points

Great for looped sample playback

Inlet 1: frequency (Hz)
Inlet 2: stop/run (zero/non-zero) (Hz)
Inlet 3: loop location (0-1)
Inlet 4: loop size (0-1)
Outlet 1: phasor signal
Outlet 2: loop phasor signal

Download
phasorloop~.zip - object, help patch, source code

Source Code
//------------------------------------------------------------------------------
//  Phasor with loop points
//
//  phasorloop~.c
//
//  Created by Cooper Baker on 08/29/15.
//  Copyright (c) 2015 Cooper Baker. All rights reserved.
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// headers
//------------------------------------------------------------------------------

// main header for pd
#include "m_pd.h"

// utility header for Pd Objects project
#include "utility.h"

// disable compiler warnings on windows
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif


//------------------------------------------------------------------------------
// phasorloop_class - pointer to this object's definition
//------------------------------------------------------------------------------
static t_class* phasorloop_class;
static t_class* phasorloop_arg_class;

//------------------------------------------------------------------------------
// phasorloop - data structure holding this object's data
//------------------------------------------------------------------------------
typedef struct phasorloop
{
    // this object - must always be first variable in struct
    t_object object;
   
    // needed for CLASS_MAINSIGNALIN macro call in phasorloop_tilde_setup
    t_float inlet_1;    // hertz          float
    t_float inlet_2;    // play           0 or 1
    t_float inlet_3;    // location       0 -- 1
    t_float inlet_4;    // size           0 -- 1
   
    // temporary output buffers
    t_float* out_temp_1;
    t_float* out_temp_2;
   
    // bytes per vector
    t_float vector_bytes;
   
    // sample rate of this object
    t_float sample_rate;
   
    // phase
    double phase;
   
    // phase increment
    double phase_inc;
   
    t_float location_prev;
    t_float size_prev;
   
} t_phasorloop;


//------------------------------------------------------------------------------
// function prototypes
//------------------------------------------------------------------------------
static t_int* phasorloop_perform     ( t_int* io );
static void   phasorloop_dsp         ( t_phasorloop* object, t_signal **sig );
static void*  phasorloop_new         ( t_symbol *s, t_int argc, t_atom *argv );
static void   phasorloop_free        ( t_phasorloop* object );
void          phasorloop_tilde_setup ( void );


//------------------------------------------------------------------------------
// phasorloop_perform - the signal processing function of this object
//------------------------------------------------------------------------------
static t_int* phasorloop_perform( t_int* io )
{
    // store variables from dsp input/output array
    t_float*       in1    = ( t_float*      )( io[ 1 ] );
    t_float*       in2    = ( t_float*      )( io[ 2 ] );
    t_float*       in3    = ( t_float*      )( io[ 3 ] );
    t_float*       in4    = ( t_float*      )( io[ 4 ] );
    t_float*       out1   = ( t_float*      )( io[ 5 ] );
    t_float*       out2   = ( t_float*      )( io[ 6 ] );
    t_int          frames = ( t_int         )( io[ 7 ] );
    t_phasorloop*  object = ( t_phasorloop* )( io[ 8 ] );
   
    // store local pointers
    t_float* out_temp_1 =  object->out_temp_1;
    t_float* out_temp_2 =  object->out_temp_2;
    double*  phase      = &object->phase;

    // clear memory
    memset( out_temp_1, 0, object->vector_bytes );
    memset( out_temp_2, 0, object->vector_bytes );
   
    // local variables
    t_float hertz;
    t_float play;
    t_float location;
    t_float size;
    t_float min;
    t_float max;
    t_float phase_inc;
   
    // signal vector iterator variable
    t_int n = -1;
   
    // the dsp loop
    while( ++n < frames )
    {
        // copy inlet values
        hertz    = in1[ n ];
        play     = in2[ n ];
        location = in3[ n ];
        size     = in4[ n ];
       
        // constrain location and size
        location = Clip( location, 0.0, 1.0 );
        size     = Clip( size,     0.0, 1.0 );
        location = Clip( location, 0.0, 1.0 - object->size_prev     );
        size     = Clip( size,     0.0, 1.0 - object->location_prev );
       
        object->location_prev = location;
        object->size_prev     = size;
       
        // calculate phase increment
        phase_inc = hertz ? 1.0 / ( ( 1.0 / hertz ) * object->sample_rate ) : 0.0;
       
        // calculate loop points
        min = location;
        max = location + size;
       
        // handle zero size
        if( ( size > 0.0 ) && ( play != 0 ) )
        {
            // increment phase
            *phase += phase_inc;

            // wrap increasing phase
            while( *phase > max )
            {
                *phase -= size;
            }
           
            // wrap decreasing phase
            while( *phase < min )
            {
                *phase += size;
            }

            // copy phase and loop phasor to temp output buffers
            out_temp_1[ n ] = *phase;
            out_temp_2[ n ] = ( *phase - min ) / size;
        }
        else
        {
            // reset phase
            *phase = min;
           
            // copy phase and loop phasor to temp output buffers
            out_temp_1[ n ] = min;
            out_temp_2[ n ] = 0.0;
        }
    }
   
    // copy temp output buffers to outputs
    memcpy( out1, out_temp_1, object->vector_bytes );
    memcpy( out2, out_temp_2, object->vector_bytes );
   
    // return the dsp input/output array address plus one more than its size
    // to provide a pointer to the next perform function in pd's call list
    return &( io[ 9 ] );
}


//------------------------------------------------------------------------------
// phasorloop_dsp - installs this object's dsp function in pd's callback list
//------------------------------------------------------------------------------
static void phasorloop_dsp( t_phasorloop* object, t_signal **sig )
{
    // store sample rate
    object->sample_rate = sig[ 0 ]->s_sr;
   
    // calculate memory size of a vector
    object->vector_bytes = sig[ 0 ]->s_n * sizeof( t_float );
   
    // reallocate temporary output vectors
    object->out_temp_1 = ( t_float* )realloc( object->out_temp_1, object->vector_bytes );
    object->out_temp_2 = ( t_float* )realloc( object->out_temp_2, object->vector_bytes );
   
    // dsp_add arguments
    //--------------------------------------------------------------------------
    // perform routine
    // number of passed parameters
    // inlet 1 sample vector
    // inlet 2 sample vector
    // inlet 3 sample vector
    // inlet 4 sample vector
    // inlet 5 sample vector
    // outlet 1 sample vector
    // outlet 2 sample vector
    // sample frames to process (vector size)
    // pointer to this object's data structure
    dsp_add( phasorloop_perform, 8, sig[ 0 ]->s_vec, sig[ 1 ]->s_vec, sig[ 2 ]->s_vec, sig[ 3 ]->s_vec, sig[ 4 ]->s_vec, sig[ 5 ]->s_vec, sig[ 0 ]->s_n, object );
}


//------------------------------------------------------------------------------
// phasorloop_new - instantiates a copy of this object in pd
//------------------------------------------------------------------------------
static void* phasorloop_new( t_symbol *s, t_int argc, t_atom *argv )
{
    // create a pointer to this object
    t_phasorloop* object = ( t_phasorloop* )pd_new( phasorloop_class );
   
    // create signal inlets
    signalinlet_new( &object->object, object->inlet_2 );
    signalinlet_new( &object->object, object->inlet_3 );
    signalinlet_new( &object->object, object->inlet_4 );
   
    // create signal outlets
    outlet_new( &object->object, gensym( "signal" ) );
    outlet_new( &object->object, gensym( "signal" ) );
   
    // initialize the values of inlet variables
    object->inlet_1 = 0;
    object->inlet_2 = 0;
    object->inlet_3 = 0;
    object->inlet_4 = 0;
   
    // initialize variables
    object->phase         = 0;
    object->location_prev = 1;
    object->size_prev     = 1;
    object->sample_rate   = 0;
    object->vector_bytes  = 0;
   
    // initialize temp buffer pointers
    object->out_temp_1 = NULL;
    object->out_temp_2 = NULL;
   
    // return pointer to this object
    return object;
}


//------------------------------------------------------------------------------
// phasorloop_free - cleans up memory allocated by this object
//------------------------------------------------------------------------------
static void phasorloop_free( t_phasorloop* object )
{
    // if memory is allocated
    if( object->out_temp_1 )
    {
        // deallocate the memory
        free( object->out_temp_1 );
       
        // set the memory pointer to null
        object->out_temp_1 = NULL;
    }
   
    // . . .
    if( object->out_temp_2 )
    {
        free( object->out_temp_2 );
        object->out_temp_2 = NULL;
    }
   
}

//------------------------------------------------------------------------------
// phasorloop_tilde_setup - describes the attributes of this object to pd so it may be properly instantiated
// (must always be named with _tilde replacing ~ in the object name)
//------------------------------------------------------------------------------
void phasorloop_tilde_setup( void )
{
    // phasorloop class
    //--------------------------------------------------------------------------
   
    // creates an instance of this object and describes it to pd
    phasorloop_class = class_new( gensym( "phasorloop~" ), ( t_newmethod )phasorloop_new, ( t_method )phasorloop_free, sizeof( t_phasorloop ), 0, 0, 0 );
   
    // declares leftmost inlet as a signal inlet
    CLASS_MAINSIGNALIN( phasorloop_class, t_phasorloop, inlet_1 );
   
    // installs phasorloop_dsp so that it will be called when dsp is turned on
    class_addmethod( phasorloop_class, ( t_method )phasorloop_dsp, gensym( "dsp" ), 0 );
   
    // announce this object in the pd console
    post( "phasorloop~: phasor with loop points - v1.0 - Cooper Baker" );
}


//------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------